package com.zoe.onelink.auth.component;

import cn.hutool.core.util.StrUtil;
import com.zoe.onelink.auth.properties.AuthProperties;
import com.zoe.onelink.upms.common.constants.SecurityConstants;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>标题: </p>
 * <p>描述:
 *      改造 {@link BearerTokenExtractor}：
 *      1. 对@InnerUrl注解标注的接口，不进行校验；
 *      2. 兼容请求头onelinkToken携带的access_token；
 * </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-02-24 15:07
 */
public class OneLinkBearerTokenExtractor extends BearerTokenExtractor {

    private final PathMatcher pathMatcher;

    private final AuthProperties authProperties;

    public OneLinkBearerTokenExtractor(AuthProperties authProperties) {
        this.authProperties = authProperties;
        this.pathMatcher = new AntPathMatcher();
    }

    @Override
    public Authentication extract(HttpServletRequest request) {
        boolean match = authProperties.getIgnoreUrls().stream()
                .anyMatch(url -> pathMatcher.match(url, request.getRequestURI()));
        if(match){
            return null;
        }

        // 从请求头中获取onelinkToken
        String tokenValue = request.getHeader(SecurityConstants.HEADER_TOKEN);
        if(StrUtil.isEmpty(tokenValue)){
            tokenValue = request.getParameter(SecurityConstants.HEADER_TOKEN);
        }
        // 获取不到onelinkToken，走OAuth2协议获取token
        if(StrUtil.isEmpty(tokenValue)){
            return super.extract(request);
        }
        return new PreAuthenticatedAuthenticationToken(tokenValue, "");
    }

}